﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using ArcEngine.Resources;
using ArcEngine.Graphics;
using ArcEngine.GUI;
using System.Reflection;
using System.IO;
using WeifenLuo.WinFormsUI.Docking;


namespace ArcEngine.Editor
{
	public partial class LayoutForm : DockContent
	{

		/// <summary>
		/// 
		/// </summary>
		/// <param name="form"></param>
		public LayoutForm()
		{
			InitializeComponent();
			RenderControl.InitializeContexts();

			SelectionBox = new SelectionBox();
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="layout"></param>
		/// <returns></returns>
		public bool Init(Layout layout)
		{

			// OpenGL control
			RenderControl.MakeCurrent();
			Video.ShareVideoContext();
			Video.Texturing = true;
			Video.Blending = true;


			CheckerBoard = new Texture("CheckerBoard");
			Stream stream = ResourceManager.GetInternalResource("ArcEngine.Files.checkerboard.png");
			CheckerBoard.LoadImage(stream);
			stream.Close();



			//
			CurrentLayout = layout;
			GuiPropertyBox.SelectedObject = CurrentLayout;
			TabText = CurrentLayout.Name;

			// Gather all elements
			RebuildElementsBox();

			//
			DrawTimer.Start();

			return true;
		}



		/// <summary>
		/// Populate the ElementsBox listview
		/// </summary>
		void RebuildElementsBox()
		{
			ElementsBox.Items.Clear();
			ElementsBox.BeginUpdate();
			foreach (GuiBase element in CurrentLayout.Elements)
				ElementsBox.Items.Add(element.Name);
			ElementsBox.EndUpdate();
		}


		/// <summary>
		/// Select an element by its name
		/// </summary>
		/// <param name="name"></param>
		void SelectElement(string name)
		{
			CurrentElement = CurrentLayout.GetElement(name);

			if (CurrentElement != null)
			{
				SelectionBox.Rectangle = CurrentElement.Rectangle;
				ElementPropertyBox.SelectedObject = CurrentElement;
				ElementsBox.SelectedItem = name;

			}
			else
			{
				SelectionBox.Rectangle = Rectangle.Empty;
				ElementPropertyBox.SelectedObject = null;
				if (ElementsBox.SelectedIndex != -1)
					ElementsBox.SetSelected(ElementsBox.SelectedIndex, false);
			}

		}


		#region Events


		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void DrawTimer_Tick(object sender, EventArgs e)
		{
			RenderControl.Draw();
		}



		/// <summary>
		/// Time to paint my dear !
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void RenderControl_Paint(object sender, PaintEventArgs e)
		{
			// Stop the draw timer
			DrawTimer.Stop();

			// Clear the background
			Video.ClearBuffers();


			// Background texture
			Video.Texture = CheckerBoard;
			Rectangle rect = new Rectangle(Point.Empty, RenderControl.Size);
			Video.Blit(rect, rect);



			// Draw the layout
			CurrentLayout.Draw();


			// Draw the selection box
			SelectionBox.Draw();

			// If no action and mouse over an element, draw its bounding box
			if (SelectionBox.MouseTool == SelectionBox.MouseTools.NoTool)
			{
				GuiBase elem = FindElementAt(RenderControl.PointToClient(Control.MousePosition));
				if (elem != null)
				{
					Video.Rectangle(elem.Rectangle, false);
				}
			}


			// Start the draw timer
			DrawTimer.Start();
		}



		/// <summary>
		/// Resize the render control
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void RenderControl_Resize(object sender, EventArgs e)
		{
			RenderControl.MakeCurrent();
			Video.ViewPort = new Rectangle(new Point(), RenderControl.Size);
		}


		/// <summary>
		/// Adds a button
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void AddButtonTool_Click(object sender, EventArgs e)
		{
			Wizards.NewGuiButtonWizard wizard = new Wizards.NewGuiButtonWizard(CurrentLayout);
			wizard.ShowDialog();

			RebuildElementsBox();
		}



		/// <summary>
		/// Element selected
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void ElementsBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (ElementsBox.SelectedIndex != -1)
				SelectElement(ElementsBox.SelectedItem.ToString());
		}


		/// <summary>
		/// Remove the selected element
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void DeleteButton_Click(object sender, EventArgs e)
		{
			if (CurrentElement != null)
			{
				CurrentLayout.DeleteElement(CurrentElement);
				SelectElement(null);
				RebuildElementsBox();
			}
		}


		/// <summary>
		/// Resize Element to fit
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void ResizeToFitButton_Click(object sender, EventArgs e)
		{
			// Is it a Button ?
			if (CurrentElement is GUI.Button)
			{
				GUI.Button button = CurrentElement as GUI.Button;
				button.ResizeToFitTexture();
			}
		}


		#endregion



		#region Main events


		/// <summary>
		/// OnMouseMove
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void RenderControl_MouseMove(object sender, MouseEventArgs e)
		{
			// If user resized the selectionbox, then resize the element
			if (SelectionBox.OnMouseMove(e))
			{
				CurrentElement.Rectangle = SelectionBox.Rectangle;
			}

		}



		/// <summary>
		/// Find the element at a location
		/// </summary>
		/// <param name="Location">Location to loook at</param>
		/// <rereturns>The GuiBase element or null if nothing</rereturns>
		private GuiBase FindElementAt(Point Location)
		{

			// Find the element under the mouse
			foreach (GuiBase element in CurrentLayout.Elements)
			{
				if (element.Rectangle.Contains(Location))
					return element;
			}


			return null;
		}


		/// <summary>
		/// OnMouseDown
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void RenderControl_MouseDown(object sender, MouseEventArgs e)
		{

			if (e.Button == MouseButtons.Left)
			{
				// Find the element under the mouse
				GuiBase elem = FindElementAt(e.Location);
				if (elem != null)
				{
					SelectElement(elem.Name);
					SelectionBox.OnMouseDown(e);
				}
				else
				{
					// Unselect the element
					SelectElement(null);
				}
			}
		}



		/// <summary>
		/// OnMouseUp
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void RenderControl_MouseUp(object sender, MouseEventArgs e)
		{
			SelectionBox.OnMouseUp(e);
		}


		/// <summary>
		/// OnMouseClick
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void RenderControl_MouseClick(object sender, MouseEventArgs e)
		{

		}


		/// <summary>
		/// OnMouseDoubleClick
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void RenderControl_MouseDoubleClick(object sender, MouseEventArgs e)
		{

		}

		#endregion



		#region Properties


		/// <summary>
		/// Layout to edit
		/// </summary>
		Layout CurrentLayout;


		/// <summary>
		/// Current element
		/// </summary>
		GuiBase CurrentElement;


		/// <summary>
		/// SelectionBox to resize gui elements
		/// </summary>
		SelectionBox SelectionBox;




		/// <summary>
		/// Background texture
		/// </summary>
		Texture CheckerBoard;
		#endregion

	}
}
